Micron Document
`:top
An `F33f`_`[SQL`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=SQL]`_`f `!INSERT`! statement adds one or more records to any single `F33f`_`[table`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Table_(database)]`_`f in a `F33f`_`[relational database`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Relational_database]`_`f.

>>Contents

• `F0af`_`[Basic form`#basic-form]`_`f
• `F0af`_`[Advanced forms`#advanced-forms]`_`f
• `F0af`_`[Multirow inserts`#multirow-inserts]`_`f
• `F0af`_`[Copying rows from other tables`#copying-rows-from-other-tables]`_`f
• `F0af`_`[Default Values`#default-values]`_`f
• `F0af`_`[Retrieving the key`#retrieving-the-key]`_`f
• `F0af`_`[Triggers`#triggers]`_`f
• `F0af`_`[References`#references]`_`f
• `F0af`_`[External links`#external-links]`_`f

-─

>>Basic form

Insert statements have the following form:

`B100`F9d9INSERT INTO table (column1 [, column2, column3 ... ]) VALUES (value1 [, value2, value3 ... ])`f`b

The number of `F33f`_`[columns`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Column_(database)]`_`f and values must be the same. If a column is not specified, the default value for the column is used. The values specified (or implied) by the INSERT statement must satisfy all the applicable constraints (such as `F33f`_`[primary keys`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Primary_key]`_`f, `F33f`_`[CHECK constraints`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Check_Constraint]`_`f, and `F33f`_`[NOT NULL`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Null_(SQL)]`_`f constraints). If a syntax error occurs or if any constraints are violated, the new row is not added to the table and an error returned instead.

Example:

`B100`F9d9INSERT INTO phone_book (name, number) VALUES ('John Doe', '555-1212');`f`b

Shorthand may also be used, taking advantage of the order of the columns when the table was created. It is not required to specify all columns in the table since any other columns will take their default value or remain `F33f`_`[null`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Null_(SQL)]`_`f:

`B100`F9d9INSERT INTO table VALUES (value1, [value2, ... ])`f`b

Example for inserting data into 2 columns in the phone_book table and ignoring any other columns which may be after the first 2 in the table.

`B100`F9d9INSERT INTO phone_book VALUES ('John Doe', '555-1212');`f`b

>>Advanced forms

>>>Multirow inserts

A SQL feature (since `F33f`_`[SQL-92`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=SQL-92]`_`f) is the use of `*row value constructors`* to insert multiple rows at a time in a single SQL statement:

`B100`F9d9INSERT INTO tablename (column-a, [column-b, ...])`f`b
`B100`F9d9VALUES ('value-1a', ['value-1b', ...]),`f`b
`B100`F9d9 ('value-2a', ['value-2b', ...]),`f`b
`B100`F9d9 ...`f`b

This feature is supported by `F33f`_`[IBM Db2`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=IBM_Db2]`_`f, `F33f`_`[SQL Server`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Microsoft_SQL_Server]`_`f (since version 10.0 - i.e. 2008), `F33f`_`[PostgreSQL`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=PostgreSQL]`_`f (since version 8.2), `F33f`_`[MySQL`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=MySQL]`_`f, `F33f`_`[SQLite`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=SQLite]`_`f (since version 3.7.11) and `F33f`_`[H2`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=H2_(DBMS)]`_`f.

Example (assuming that 'name' and 'number' are the only columns in the 'phone_book' table):

`B100`F9d9INSERT INTO phone_book VALUES ('John Doe', '555-1212'), ('Peter Doe', '555-2323');`f`b

which may be seen as a shorthand for the two statements

`B100`F9d9INSERT INTO phone_book VALUES ('John Doe', '555-1212');`f`b
`B100`F9d9INSERT INTO phone_book VALUES ('Peter Doe', '555-2323');`f`b

Note that the two separate statements may have different semantics (especially with respect to statement `F33f`_`[triggers`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Database_trigger]`_`f) and may not provide the same performance as a single multi-row insert.

To insert multiple rows in MS SQL you can use such a construction:

`B100`F9d9INSERT INTO phone_book`f`b
`B100`F9d9SELECT 'John Doe', '555-1212'`f`b
`B100`F9d9UNION ALL`f`b
`B100`F9d9SELECT 'Peter Doe', '555-2323';`f`b

Note that this is not a valid SQL statement according to the SQL standard (`F33f`_`[SQL:2003`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=SQL:2003]`_`f) due to the incomplete subselect clause.

To do the same in Oracle use the `F33f`_`[DUAL table`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=DUAL_table]`_`f, which always consists of a single row only:

`B100`F9d9INSERT INTO phone_book`f`b
`B100`F9d9SELECT 'John Doe', '555-1212' FROM DUAL`f`b
`B100`F9d9UNION ALL`f`b
`B100`F9d9SELECT 'Peter Doe','555-2323' FROM DUAL`f`b

A standard-conforming implementation of this logic shows the following example, or as shown above:

`B100`F9d9INSERT INTO phone_book`f`b
`B100`F9d9SELECT 'John Doe', '555-1212' FROM LATERAL ( VALUES (1) ) AS t(c)`f`b
`B100`F9d9UNION ALL`f`b
`B100`F9d9SELECT 'Peter Doe','555-2323' FROM LATERAL ( VALUES (1) ) AS t(c)`f`b

Oracle PL/SQL supports the INSERT ALL statement, where multiple insert statements are terminated by a SELECT:`:cite-ref-1[`F5bf`_`[1`#cite-note-1]`_`f]

`B100`F9d9INSERT ALL`f`b
`B100`F9d9INTO phone_book VALUES ('John Doe', '555-1212')`f`b
`B100`F9d9INTO phone_book VALUES ('Peter Doe', '555-2323')`f`b
`B100`F9d9SELECT * FROM DUAL;`f`b

In `F33f`_`[Firebird`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Firebird_(database_server)]`_`f inserting multiple rows can be achieved like this:

`B100`F9d9INSERT INTO phone_book (name, number)`f`b
`B100`F9d9SELECT 'John Doe', '555-1212' FROM RDB$DATABASE`f`b
`B100`F9d9UNION ALL`f`b
`B100`F9d9SELECT 'Peter Doe', '555-2323' FROM RDB$DATABASE;`f`b

Firebird, however, restricts the number of rows than can be inserted in this way, since there is a limit to the number of contexts that can be used in a single query.

>>>Copying rows from other tables

An INSERT statement can also be used to retrieve data from other tables, modify it if necessary and insert it directly into the table. All this is done in a single SQL statement that does not involve any intermediary processing in the client application. A subselect is used instead of the VALUES clause. The subselect can contain joins, function calls, and it can even query the same table into which the data is inserted. Logically, the select is evaluated before the actual insert operation is started. An example is given below.

`B100`F9d9INSERT INTO phone_book2`f`b
`B100`F9d9SELECT *`f`b
`B100`F9d9FROM phone_book`f`b
`B100`F9d9WHERE name IN ('John Doe', 'Peter Doe')`f`b

A variation is needed when some of the data from the source table is being inserted into the new table, but not the whole record. (Or when the tables' `F33f`_`[schemas`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Database_schema]`_`f are not the same.)

`B100`F9d9INSERT INTO phone_book2 (name, number)`f`b
`B100`F9d9SELECT name, number`f`b
`B100`F9d9FROM phone_book`f`b
`B100`F9d9WHERE name IN ('John Doe', 'Peter Doe')`f`b

The SELECT statement produces a (temporary) table, and the schema of that temporary table must match with the schema of the table where the data is inserted into.

>>Default Values

It is possible to insert a new row without specifying any data, using default values for all columns. However, some databases reject the statement if no data is given, such as Microsoft SQL Server, and in this case the DEFAULT keyword can be used.

`B100`F9d9INSERT INTO phone_book`f`b
`B100`F9d9VALUES ( DEFAULT )`f`b

Sometimes databases also support alternative syntax for this; for example, MySQL allows omitting the DEFAULT keyword, and T-SQL can use DEFAULT VALUES instead of VALUES(DEFAULT). The DEFAULT keyword can also be used in normal insertion to explicitly fill a column using that column's default value:

`B100`F9d9INSERT INTO phone_book VALUES ( DEFAULT, '555-1212' )`f`b

What happens when a column does not specify a default value is database dependent. For example, MySQL and SQLite will fill in with a blank value (except when in strict mode), while many other databases will reject the statement.

>>Retrieving the key

Database designers that use a `F33f`_`[surrogate key`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Surrogate_key]`_`f as the primary key for every table will run into the occasional scenario where they need to automatically retrieve the database-generated primary key from an SQL INSERT statement for use in other SQL statements. Most systems do not allow SQL INSERT statements to return row data. Therefore, it becomes necessary to implement a workaround in such scenarios. Common implementations include:

• Using a database-specific `F33f`_`[stored procedure`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Stored_procedure]`_`f that generates the surrogate key, performs the INSERT operation, and finally returns the generated key. For example, in Microsoft SQL Server, the key is retrieved via the SCOPE_IDENTITY() special function, while in SQLite the function is named last_insert_rowid().
• Using a database-specific `F33f`_`[SELECT`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Select_(SQL)]`_`f statement on a temporary table containing last inserted row(s). Db2 implements this feature in the following way: SELECT * FROM NEW TABLE ( INSERT INTO phone_book VALUES ( 'Peter Doe','555-2323' ) ) AS t

• Db2 for `F33f`_`[z/OS`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Z/OS]`_`f implements this feature in the following way. SELECT EMPNO, HIRETYPE, HIREDATE FROM FINAL TABLE ( INSERT INTO EMPSAMP (NAME, SALARY, DEPTNO, LEVEL) VALUES('Mary Smith', 35000.00, 11, 'Associate') );

• Using a `F33f`_`[SELECT`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Select_(SQL)]`_`f statement after the INSERT statement with a database-specific function that returns the generated primary key for the most recently inserted row. For example, LAST_INSERT_ID() for `F33f`_`[MySQL`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=MySQL]`_`f.
• Using a unique combination of elements from the original SQL INSERT in a subsequent SELECT statement.
• Using a `F33f`_`[GUID`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=GUID]`_`f in the SQL INSERT statement and retrieving it in a SELECT statement.
• Using the OUTPUT clause in the SQL INSERT statement for MS-SQL Server 2005 and MS-SQL Server 2008.
• Using an INSERT statement with RETURNING clause for `F33f`_`[Oracle`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Oracle_database]`_`f. INSERT INTO phone_book VALUES ( 'Peter Doe','555-2323' ) RETURNING phone_book_id INTO v_pb_id
• Using an INSERT statement with RETURNING clause for `F33f`_`[PostgreSQL`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=PostgreSQL]`_`f (since 8.2). The returned list is identical to the result of a INSERT.

• `F33f`_`[Firebird`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Firebird_(database_server)]`_`f has the same syntax in Data Modification Language statements (DSQL); the statement may add at most one row.`:cite-ref-2[`F5bf`_`[2`#cite-note-2]`_`f] In stored procedures, triggers and execution blocks (PSQL) the aforementioned Oracle syntax is used.`:cite-ref-3[`F5bf`_`[3`#cite-note-3]`_`f] INSERT INTO phone_book VALUES ( 'Peter Doe','555-2323' ) RETURNING phone_book_id

• Using the IDENTITY() function in `F33f`_`[H2`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=H2_(DBMS)]`_`f returns the last identity inserted. SELECT IDENTITY();

>>Triggers

If `F33f`_`[triggers`:/page/wikibook/entry.mu`zim=wikipedia_en_all_nopic_2025-08.zim|entry_path=Database_trigger]`_`f are defined on the table on which the INSERT statement operates, those triggers are evaluated in the context of the operation. BEFORE INSERT triggers allow the modification of the values that shall be inserted into the table. AFTER INSERT triggers cannot modify the data anymore, but can be used to initiate actions on other tables, for example, to implement auditing mechanism.

>>References

`:cite-note-1`!1.`! `F0af`_`[↑`#cite-ref-1]`_`f "Oracle PL/SQL: INSERT ALL". `*psoug.org`*. Archived from the original on 2010-09-16. Retrieved 2010-09-02.
`:cite-note-2`!2.`! `F0af`_`[↑`#cite-ref-2]`_`f "Firebird 2.5 Language Reference Update". Retrieved 2011-10-24.
`:cite-note-3`!3.`! `F0af`_`[↑`#cite-ref-3]`_`f "Firebird SQL Language Dictionary".

>>External links

• Oracle SQL INSERT statement (Oracle Database SQL Language Reference, 11g Release 2 (11.2) on oracle.com)
• Microsoft Access Append Query Examples and SQL INSERT Query Syntax
• MySQL INSERT statement (MySQL 5.5 Reference Manual)

`c`F0af`_`[↑ Back to top`#top]`_`f`a